package com.code.monitor.handler;

import com.code.monitor.constants.Constants;
import com.code.monitor.constants.MessageType;
import com.code.monitor.constants.SerializableType;
import com.code.monitor.message.Message;
import com.code.monitor.message.SerializableMessage;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;

import java.nio.charset.Charset;
import java.util.List;

/**
 * @author ggh
 * @date 2023/4/15
 */
@ChannelHandler.Sharable
public class SerializableMessageCodec extends MessageToMessageCodec<ByteBuf, SerializableMessage> {

    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, SerializableMessage message, List<Object> list) throws Exception {
        ByteBuf byteBuf = channelHandlerContext.alloc().buffer();
        byteBuf.writeByte(message.getSerializableType());
        byteBuf.writeByte(message.getType());

        byte[] bytes = SerializableType.parseType(message.getSerializableType()).serializable(message);
        byteBuf.writeInt(bytes.length);
        byteBuf.writeBytes(bytes);

        list.add(byteBuf);
    }

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        // 魔数
        byteBuf.readCharSequence(Constants.MAGIC_NUM.length(), Charset.defaultCharset());

        // 处理序列化方式和消息类型
        byte serializableType = byteBuf.readByte();
        byte messageType = byteBuf.readByte();
        int len = byteBuf.readInt();

        byte[] bytes = new byte[len];
        byteBuf.readBytes(bytes);
        SerializableType serializableTool = SerializableType.parseType(serializableType);
        MessageType msgType = MessageType.parseType(messageType);
        Message message = serializableTool.deserizable(bytes, msgType.getParseClass());

        list.add(message);
    }
}
